<?php

namespace app\admin\service\material;

use app\admin\logic\material\Category as CategoryLogic;
use app\admin\logic\material\Material as MaterialLogic;
use app\admin\logic\system\Config as SystemConfig;
use app\common\exception\LogicException;
use app\common\library\Queue;
use app\common\logic\Attach;
use app\common\service\BaseService;
use eduline\admin\libs\pageform\FormItem;
use eduline\admin\page\PageList;
use Exception;
use think\annotation\Inject;
use think\db\exception\DbException;
use think\facade\{Db, Request};
use eduline\upload\Client as FileClient;
use think\Response;

class Material extends BaseService
{
    /**
     * @Inject()
     *
     * @var MaterialLogic
     */
    protected $materialLogic;

    /**
     * @Inject()
     *
     * @var CategoryLogic
     */
    protected $categoryLogic;

    /**
     * @Inject()
     * @var Attach
     */
    protected $attach;

    /**
     * 图片素材管理
     *
     * @return Response
     * @throws DbException
     */
    public function picture()
    {
        // 取得分组数据
        $category = $this->categoryLogic->getList('picture')->hidden(['update_time', 'material_type'])->toArray();
        $list     = new PageList();

        // 未分组的图片数量
        $count = $this->materialLogic->getUncategoryCount('picture');
        array_unshift($category, ['id' => -1, 'title' => '默认分组', 'num' => $count]);

        $list->category = [
            [
                'id'       => 0,
                'title'    => '全部分组(' . array_sum(array_column($category, 'num')) . ')',
                'children' => $category,
            ],
        ];

        $list->searchKey = [
            'filename' => FormItem::make()->title(false)->placeholder('图片名称'),
        ];

        $map    = [
            'filename' => Request::get('filename', ''),
            'category' => Request::get('category', 0),
        ];
        $delete = Request::get('recycle/d', 0);

        $datas = $this->materialLogic->getList('picture', $map, $delete);

        $list->datas = $datas;

        return $list->send();
    }

    /**
     * 音频素材管理
     *
     * @return Response
     * @throws DbException
     */
    public function audio()
    {
        // 取得分组数据
        $category = $this->categoryLogic->getList('audio')->hidden(['update_time', 'material_type'])->toArray();
        $list     = new PageList();
        // 未分组的图片数量
        $count = $this->materialLogic->getUncategoryCount('audio');
        array_unshift($category, ['id' => -1, 'title' => '默认分组', 'num' => $count]);
        $list->category = [
            [
                'id'       => 0,
                'title'    => '全部分组(' . array_sum(array_column($category, 'num')) . ')',
                'children' => $category,
            ],
        ];

        $list->searchKey = [
            'filename' => FormItem::make()->title(false)->placeholder('音频名称'),
        ];

        $map    = [
            'filename' => Request::get('filename', ''),
            'category' => Request::get('category', 0),
        ];
        $delete = Request::get('recycle/d', 0);

        $datas = $this->materialLogic->getList('audio', $map, $delete);

        $list->datas = $datas;

        return $list->send();
    }

    /**
     * 视频素材管理
     *
     * @return Response
     * @throws DbException
     */
    public function video()
    {
        // 取得分组数据
        $category = $this->categoryLogic->getList('video')->hidden(['update_time', 'material_type'])->toArray();
        $list     = new PageList();
        // 未分组的图片数量
        $count = $this->materialLogic->getUncategoryCount('video');
        array_unshift($category, ['id' => -1, 'title' => '默认分组', 'num' => $count]);
        $list->category = [
            [
                'id'       => 0,
                'title'    => '全部分组(' . array_sum(array_column($category, 'num')) . ')',
                'children' => $category,
            ],
        ];

        $list->searchKey = [
            'filename' => FormItem::make()->title(false)->placeholder('视频名称'),
        ];

        $map    = [
            'filename' => Request::get('filename', ''),
            'category' => Request::get('category', 0),
        ];
        $delete = Request::get('recycle/d', 0);

        $datas = $this->materialLogic->getList('video', $map, $delete);

        $list->datas = $datas;

        //
        $uploadConf   = SystemConfig::get('system.package.upload', [], request()->mhm_id);
        $list->bokecc = ($uploadConf['stock'] ?? '') == 'bokecc';

        return $list->send();
    }

    /**
     * 文件素材管理
     *
     * @return Response
     * @throws DbException
     */
    public function file()
    {
        // 取得分组数据
        $category = $this->categoryLogic->getList('file')->hidden(['update_time', 'material_type'])->toArray();
        $list     = new PageList();
        // 未分组的图片数量
        $count = $this->materialLogic->getUncategoryCount('file');
        array_unshift($category, ['id' => -1, 'title' => '默认分组', 'num' => $count]);
        $list->category = [
            [
                'id'       => 0,
                'title'    => '全部分组(' . array_sum(array_column($category, 'num')) . ')',
                'children' => $category,
            ],
        ];

        $list->searchKey = [
            'filename' => FormItem::make()->title(false)->placeholder('文件名称'),
        ];

        $map = [
            'filename' => Request::get('filename', ''),
            'category' => Request::get('category', 0),
        ];

        $delete = Request::get('recycle/d', 0);

        $datas = $this->materialLogic->getList('file', $map, $delete);

        $list->datas = $datas;

        return $list->send();
    }

    /**
     * 文件重命名
     *
     * @param int $id
     * @return Response
     */
    public function updateMaterial(int $id)
    {

        $field = Request::param('field');
        $value = Request::put($field);

        $this->materialLogic->updateMaterial($field, $value, $id);

        return $this->parseToData([], 1, '操作成功');
    }

    /**
     * 删除素材-软删除/真删除
     *
     * @param $id
     * @param $really
     * @return Response
     */
    public function delete($id, $really = false)
    {
        if ($really) {
            $this->materialLogic->deleteMaterialReally($id);
        } else {
            $this->materialLogic->deleteMaterial($id);
        }

        return $this->parseToData([], 1, '删除成功');
    }

    /**
     * 移动素材
     *
     * @return Response
     */
    public function move()
    {
        $ids      = Request::post('id/a');
        $category = Request::post('category/d');

        $this->materialLogic->moveMaterial($ids, $category);

        return $this->parseToData([], 1, '移动分组成功');
    }

    /**
     * 上传素材
     *
     * @return Response
     */
    public function upload()
    {
        $category = Request::post('category/d', -1);
        $type     = Request::post('material_type/s', 'file');
        $ids      = Request::post('attach_ids/a', []);

        $count = $this->materialLogic->addMaterial($ids, $type, $category);

        return $this->parseToData([], 1, '成功上传' . $count . '个素材');
    }

    /**
     * bokeccVideoSync
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/12/09
     *
     * @return Response
     */
    public function bokeccVideoSync()
    {
        //
        $param = Request::post();
        $file = new FileClient();
        $data = $file->getVideoList($param);
        //
        if (isset($data['videos']) && count($data['videos']['video'])) {
            $count = 0;
            foreach ($data['videos']['video'] as $item) {
                $exist = $this->attach->where('savename', $item['id'])->findOrEmpty();
                if (!$exist->isEmpty()) continue;
                // 附件分类
                $materialCate = $this->categoryLogic->where('cloud_id', $item['category'])->findOrEmpty();
                if ($materialCate->isEmpty()) continue;

                Db::startTrans();
                try {
                    $save   = [
                        'bucket'    => 'bokecc',
                        'stock'     => 'bokecc',
                        'to_stock'  => 'bokecc',
                        'savename'  => $item['id'],
                        'filename'  => $item['title'] . '.mp4',
                        'filehash'  => '',
                        'filemd5'   => '',
                        'mimetype'  => 'video/mp4',
                        'extension' => 'mp4',
                        'cover_url' => $item['image'],
                        'duration'  => $item['duration'],
                        'filesize'  => $item['originalsize'],
                        'status'    => 1
                    ];
                    $create = Attach::create($save);
                    if ($create->isEmpty()) throw new LogicException('attach error');
                    // 附件分类
                    $materialCate->num += 1;
                    if (!$materialCate->save()) throw new LogicException('material category num error');
                    //
                    $md = [
                        'material_type'        => 3,
                        'attach_id'            => $create->id,
                        'material_category_id' => $materialCate->isEmpty() ? -1 : $materialCate->id,
                        'admin_user_id'        => request()->admin_user_id,
                        'mhm_id'               => request()->mhm_id,
                        'update_time'          => time()
                    ];
                    if (!Db::name('material')->save($md)) throw new LogicException('material error');

                    Db::commit();
                    $count += 1;
                } catch (LogicException|Exception $e) {
                    Db::rollback();
                    throw new LogicException($e->getMessage());
                }
            }
            if (!$count) throw new LogicException('当前页视频已同步');

            return static::parseToData([], 1, '成功同步' . $count . '个视频');
        } else {
            throw new LogicException('暂无视频可同步');
        }
    }

    /**
     * 同步云端视频到本地
     *
     * @return Response
     */
    public function syncVideoToLocal()
    {
        $mhmId = request()->mhm_id;
        // 检测是否配置了自己的储存空间
        $config = SystemConfig::get('system.package.upload.sync', [], $mhmId);
        // 是否设置了使用平台配置
        if ($mhmId != 1 && isset($config['use_platform']) && $config['use_platform'] === 1) {
            throw new LogicException('当前使用了平台储存，无法执行同步');
        }
        // 当前上传配置
        $uploadConfig = SystemConfig::get('system.package.upload', [], $mhmId);
        if ($uploadConfig['stock'] === 'local') {
            throw new LogicException('当前上传配置储存在本地，无法执行同步');
        }
        // 从第三方同步到本地
        $post = Request::post();
        if ($post['stock'] !== 'tencent') {
            $params = [
                // 开始页数
                'pageNo'      => $post['start_page'] ?? 1,
                // 每页大小
                'pageSize'    => $post['page_size'] ?? 10,
                // 结束页
                'endPage'     => $post['end_page'] ?? 0,
                // 本次任务累计同步数量
                'count'       => 0,
                // 需要同步的云端
                'fromStock'   => $post['stock'],
                // 机构id
                'mhmId'       => $mhmId,
                // 操作的用户id
                'adminUserId' => request()->admin_user_id,
            ];
            try {
                // 推送同步任务
                Queue::push('SyncVideoToLocal', $params);

                return $this->parseToData([], 1, '任务将在后台执行，同步结果将在【系统消息】中显示');
            } catch (Exception $exception) {
                throw new LogicException('同步失败');
            }
        } else {
            // 腾讯储存使用上传文件方式同步
            $attachId = $post['attach_id'];

            try {
                // 推送同步任务
                Queue::push('SyncVideoToLocal', [
                    'fromStock'   => 'tencent',
                    'adminUserId' => request()->admin_user_id,
                    'attach_id'   => $attachId
                ]);

                return $this->parseToData([], 1, '任务将在后台执行，同步结果将在【系统消息】中显示');
            } catch (Exception $exception) {
                throw new LogicException('同步失败');
            }
        }

    }
}
